# Chapter 10. Server-Side Includes

#### Contents:

File Size
File Modification Time
Includes
Execute CGI
Echo
XBitHack
XSSI

The object of this set of facilities is to allow statements that trigger further actions to be put into served documents. The same results could be achieved by CGI scripts -- either shell scripts or specially written C programs -- but server-side includes often do what is wanted with a lot less effort. The range of possible actions is immense, so we will just give basic illustrations of each command in a number of text files in ... /htdocs.

The Config file for this site (... /site.ssi) is as follows:

>     User webuser
>     Group webgroup
>     ServerName www.butterthlies.com
>     DocumentRoot /usr/www/site.ssi/htdocs
>     ScriptAlias /cgi-bin /usr/www/cgi-bin
>     AddHandler server-parsed shtml
>     Options +Includes

The key lines are indicated in bold print.

shtml is the normal extension for HTML scripts with server-side includes in them, and is found as the extension to the relevant files in ... /htdocs. We could just as well use brian or #dog_run as long as it appears the same there, in the file with the relevant command, and in the configuration file. Using html can be useful -- for instance, you can easily implement site-wide headers and footers -- but it does mean that every HTML page gets parsed by the SSI engine. On busy systems, this could reduce performance.

Bear in mind that HTML generated by a CGI script does not get put through the SSI processor, so it's no good including the markup listed in this chapter in a CGI script.

`Options` `Includes` turns on processing of SSIs. As usual, look in the error_log if things don't work. The error messages passed to the client are necessarily uninformative since they are probably being read three continents away, where nothing useful can be done about them.

The trick is to insert special strings into our documents, which then get picked up by Apache on their way through, tested against reference strings using =, !=, <, <=, >, and >=; and then replaced by dynamically written messages. As we will see, the strings have a deliberately unusual form so they won't get confused with more routine stuff. The syntax of a command is:

>     <!--#element attribute=value attribute=value ... -->

The Apache manual tells us what the elements are:

`config`

  This command controls various aspects of the parsing. The valid attributes are as follows:

  `errmsg`

    The value is a message that is sent back to the client if an error occurs during document parsing.

  `sizefmt`

    The value sets the format to be used when displaying the size of a file. Valid values are `bytes` for a count in bytes, or `abbrev` for a count in kilobytes or megabytes as appropriate.

  `timefmt`

    The value is a string to be used by the `strftime( )` library routine when printing dates.

`echo`

  This command prints one of the `include` variables, defined later in this chapter. If the variable is unset, it is printed as `(none)`. Any dates printed are subject to the currently configured `timefmt`. The only attribute is:

  `var`

    The value is the name of the variable to print.

`exec`

  The `exec` command executes a given shell command or CGI script. `Options` `IncludesNOEXEC` disables this command completely -- a boon to the prudent webmaster. The valid attribute is:

  `cgi`

    The value specifies a %-encoded URL relative path to the CGI script. If the path does not begin with a slash, it is taken to be relative to the current document. The document referenced by this path is invoked as a CGI script, even if the server would not normally recognize it as such. However, the directory containing the script must be enabled for CGI scripts (with `ScriptAlias` or the `ExecCGI` option). The protective wrapper suEXEC will be applied if it is turned on. The CGI script is given the `PATH_INFO` and query string (`QUERY_STRING`) of the original request from the client; these cannot be specified in the URL path. The `include` variables will be available to the script in addition to the standard CGI environment. If the script returns a `Location` header instead of output, this is translated into an HTML anchor. If `Options` `IncludesNOEXEC` is set in the Config file, this command is turned off. The`include` `virtual` element should be used in preference to `exec` `cgi`.

`cmd`

  The server executes the given string using /bin/sh. The `include` variables are available to the command. If `Options` `IncludesNOEXEC` is set in the Config file, this is turned off.

`fsize`

  This command prints the size of the specified file, subject to the `sizefmt` format specification. The attributes are as follows:

  `file`

    The value is a path relative to the directory containing the current document being parsed.

  `virtual`

    The value is a %-encoded URL path relative to the current document being parsed. If it does not begin with a slash, it is taken to be relative to the current document.

`flastmod`

  This command prints the last modification date of the specified file, subject to the `timefmt` format specification. The attributes are the same as for the `fsize` command.

`include`

  Includes other Config files immediately at that point in parsing -- right there and then, not later on. Any included file is subject to the usual access control. If the directory containing the parsed file has `Options` `IncludesNOEXEC` set and including the document causes a program to be executed, it isn't included: this prevents the execution of CGI scripts. Otherwise, CGI scripts are invoked as normal using the complete URL given in the command, including any query string.

  An attribute defines the location of the document; the inclusion is done for each attribute given to the `include` command. The valid attributes are as follows.

`file`

  The value is a path relative to the directory containing the current document being parsed. It can't contain `../`, nor can it be an absolute path. The `virtual` attribute should always be used in preference to this one.

`virtual`

  The value is a %-encoded URL relative to the current document being parsed. The URL cannot contain a scheme or hostname, only a path and an optional query string. If it does not begin with a slash, then it is taken to be relative to the current document. A URL is constructed from the attribute's value, and the server returns the same output it would have if the client had requested that URL. Thus, included files can be nested. A CGI script can still be run by this method even if `Options` `IncludesNOEXEC` is set in the Config file. The reasoning is that clients can run the CGI anyway by using its URL as a hot link or simply typing it into their browser, so no harm is done by using this method (unlike `cmd` or `exec`).

## 10.1. File Size

The `fsize` command allows you to report the size of a file inside a document. The file size.shtml is as follows:

>     <!--#config errmsg="Bungled again!"-->
>     <!--#config sizefmt="bytes"-->
>     The size of this file is <!--#fsize file="size.shtml"--> bytes.
>     The size of another_file is <!--#fsize file="another_file"--> bytes.

The first line provides an error message. The second line means that the size of any files is reported in bytes printed as a number, for instance, 89. Changing `bytes` to `abbrev` gets the size in kilobytes, printed as `1k`. The third line prints the size of size.shtml itself; the fourth line prints the size of another_file. You can't comment out lines with the "`#` " character since it just prints, and the following command is parsed straight away. `config` commands must come above commands that might want to use them.

You can replace the word `file=` in this script, and in those which follow, with `virtual=`, which gives a %-encoded URL path relative to the current document being parsed. If it does not begin with a slash, it is taken to be relative to the current document.

If you play with this stuff, you find that Apache is picky about the syntax. For instance, trailing spaces cause an error:

>     The size of this file is <!--#fsize file="size.shtml   "--> bytes.
>     The size of this file is Bungled again! bytes

If we had not used the `errmsg` command, we would see the following:

>     ...[an error occurred while processing this directive]...

Copyright © 2001 O'Reilly & Associates. All rights reserved.